// uvm_tb/sequences/binary_alu_base_seq.sv
`ifndef BINARY_ALU_BASE_SEQ_SV
`define BINARY_ALU_BASE_SEQ_SV

class binary_alu_base_seq extends uvm_sequence #(binary_alu_transaction);

    // ========================================================================
    // UVM Macros
    // ========================================================================
    `uvm_object_utils(binary_alu_base_seq)

    // ========================================================================
    // Constructor
    // ========================================================================
    function new(string name = "binary_alu_base_seq");
        super.new(name);
    endfunction

    // ========================================================================
    // UVM Body Task
    // ========================================================================
    virtual task body();
        // Base sequence does nothing, derived sequences will implement tests
    endtask

endclass : binary_alu_base_seq

// ============================================================================
// Test Case 1: Mode 0 - Top Bypass Sequence
// ============================================================================
class seq_mode0_bypass extends binary_alu_base_seq;
    `uvm_object_utils(seq_mode0_bypass)

    function new(string name = "seq_mode0_bypass");
        super.new(name);
    endfunction

    virtual task body();
        `uvm_info("SEQUENCE", "Starting Mode 0 Bypass sequence", UVM_LOW)

        req = binary_alu_transaction::type_id::create("req");
        start_item(req);

        assert (req.randomize() with {
            mode == 0;
            send_left == 0;
            send_bottom == 0;
        });
        `uvm_info("SEQUENCE", "Generate new transaction:", UVM_LOW)
        req.print();

        finish_item(req);

        // Get the scoreboard handle and push the expected transaction
        // This is a simplified approach. A better way is via analysis ports.
        // uvm_test_top.m_env.m_scoreboard.push_expected(req);

        `uvm_info("SEQUENCE", "Finished Mode 0 Bypass sequence", UVM_LOW)
    endtask
endclass

// ============================================================================
// Test Case 3: Mode 3 - Dual Input Sequence
// ============================================================================
class seq_mode3_dual_input extends binary_alu_base_seq;
    `uvm_object_utils(seq_mode3_dual_input)

    function new(string name = "seq_mode3_dual_input");
        super.new(name);
    endfunction

    virtual task body();
        `uvm_info("SEQUENCE", "Starting Mode 3 Dual Input sequence", UVM_LOW)

        req = binary_alu_transaction::type_id::create("req");
        start_item(req);

        assert (req.randomize() with {mode == 3;});

        `uvm_info("SEQUENCE", "Generate new transaction:", UVM_LOW)
        req.print();

        finish_item(req);

        // Get the scoreboard handle and push the expected transaction
        // This is a simplified approach. A better way is via analysis ports.
        // uvm_test_top.m_env.m_scoreboard.push_expected(req);

        `uvm_info("SEQUENCE", "Finished Mode 3 Dual Input sequence", UVM_LOW)
    endtask
endclass

`endif  // BINARY_ALU_BASE_SEQ_SV
